
using System;

namespace raycsharp
{


public class Vector {
	public double x { get; set; } 
	public double y { get; set; } 
	public double z { get; set; } 
	public Vector(double _x,double _y,double _z) {
		x = _x;
		y = _y; 
		z = _z;
	}
	
	public Vector() : this(0.0,0.0,0.0) { }
		
	public Vector(Vector _vector) : this(_vector.x, _vector.y, _vector.z) { }
	
	public double dot_product(Vector _vector) {
		return x*_vector.x+ y*_vector.y+ z*_vector.z;
	}

	public Vector cross_product(Vector _vector) {
		
		return new Vector(y*_vector.z - z*_vector.y, z*_vector.x - x*_vector.z,x*_vector.y - y*_vector.x);
	}

	public Vector scalar_product(double _value) {
		return new Vector(x*_value,y*_value,z*_value);
	}

	public Vector normalize() {
		Vector normalized = new Vector(x,y,z);
		double mod = normalized.dot_product(normalized);
		if(mod != 0.0) { 
			normalized = normalized.scalar_product(1.0/Math.Sqrt(mod));
			
		}
		return normalized;
	}

	public Vector sub_vect(Vector _vector) {
		return new Vector(this.x-_vector.x,
			              this.y-_vector.y,
			              this.z-_vector.z);
	}

	public double length() {
		return Math.Sqrt(this.dot_product(this));
	}

	public double distance(Vector _vector) {
		return Math.Sqrt((x - _vector.x)*(x - _vector.x) + (y - _vector.y)*(y - _vector.y) + (z - _vector.z)*(z - _vector.z));
	}


	public static double operator*(Vector vector, Vector _vector) {
		return vector.dot_product(_vector);
	}

	public static Vector operator*(Vector vector, double _value) {
		return vector.scalar_product(_value);
	}

	public static Vector operator+(Vector vector, Vector _vector) {
		return new Vector(vector.x + _vector.x,vector.y + _vector.y,vector.z + _vector.z);
	}

	public static Vector operator-(Vector vector) {
		return new Vector(-vector.x,-vector.y,-vector.z);
	}

	public static Vector operator-(Vector vector, Vector _vector) {
		return vector.sub_vect(_vector);
	}

	public void debug() {
		Console.WriteLine("x: " + x + ", y: " + y +" z: " + z);
	}
}


}
